

package com.apiserver.data.mybatis.util;


import com.apiserver.data.Exception.DataException;
import com.apiserver.data.Exception.ErrCode;
import com.apiserver.data.annotation.NameStyle;
import com.apiserver.data.annotation.Style;
import com.apiserver.data.annotation.Table;
import com.apiserver.data.mybatis.model.ColumnProperty;
import com.apiserver.data.mybatis.model.EntityTable;
import com.apiserver.data.mybatis.reflet.ColumnPropertyUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author feizhou
 * @Description 实体类工具
 * @Param
 * @return 
 **/

@Slf4j
public class EntityUtil {

	/**
	 * 存储实体类对象
	 */
	private static final Map<Class<?>, EntityTable> entityTableMap = new ConcurrentHashMap<>();

	/**
	 * 获取表对象
	 *
	 * @return
	 */
	public static EntityTable getEntityTable(Class entityClass) {
		EntityTable entityTable = getEntityTableWithoutParams(entityClass);
		return entityTable;
	}




	/**
	 * 获取表对象
	 *
	 * @return
	 */
	public static EntityTable getEntityTable(Object obj) {
		EntityTable entityTable = getEntityTableWithoutParams(obj);
		return entityTable;
	}





	/**
	 * @Author feizhou
	 * @Description 获取实体表
	 * @Date 下午 6:21 2019/10/8 0008
	 * @Param [entityClass]
	 * @return com.apiserver.data.mybatis.model.EntityTable
	 **/
	
	public static EntityTable getEntityTableWithoutParams(Class entityClass) {

		EntityTable entityTable = entityTableMap.get(entityClass);
		if (entityTable == null){
			initEntityNameMap(entityClass);
		}


		entityTable = entityTableMap.get(entityClass);
		return entityTable;
	}

	/**
	 * @Author feizhou
	 * @Description 设置实体的信息
	 * @Date 下午 4:45 2019/10/8 0008
	 * @Param [obj]
	 * @return com.apiserver.data.mybatis.model.EntityTable
	 **/
	
	public static EntityTable getEntityTableWithoutParams(Object obj) {
		Class<?> entityClass = obj.getClass();
		EntityTable entityTable = entityTableMap.get(entityClass);
		if (entityTable == null){
			initEntityNameMap(entityClass);
		}
		entityTable = entityTableMap.get(entityClass);
		return entityTable;
	}



	/**
	 * @Author feizhou
	 * @Description 初始化实体属性
	 * @Date 下午 1:27 2019/10/9 0009
	 * @Param [entityClass]
	 * @return void
	 **/

	private synchronized static void initEntityNameMap(Class<?> entityClass) {

		//如果实体存在，就不初始化
		if (entityTableMap.get(entityClass) != null){
			return;
		}


		Style style = Style.camelhumpAndLowercase;// 默认驼峰命名法

		// style，该注解优先于全局配置
		if (entityClass.isAnnotationPresent(NameStyle.class)){
			style = entityClass.getAnnotation(NameStyle.class).value();
		}


		// 创建并缓存EntityTable
		EntityTable entityTable = new EntityTable(entityClass);


		//实体类需要table注解
		if (!entityClass.isAnnotationPresent(Table.class)){
			throw new DataException(ErrCode.table_Not_Exist);
		}



		Table table = entityClass.getAnnotation(Table.class);
		//表名存在的情况
		if (!table.name().equals("")) {
			entityTable.setTableName(table.name());
		}else {
			String tableName = StyleUtil.convertByStyle(entityClass.getSimpleName(), style);
			entityTable.setTableName(table.prefix()+tableName);
		}

		//字段转换方式
		entityTable.setStyle(style);

//		// 处理所有列

		List<ColumnProperty> columnProperties = ColumnPropertyUtil.getColumnProperties(entityClass, style);










		buildEntityTable(entityTable,columnProperties);


		entityTableMap.put(entityClass, entityTable);
	}

	/**
	 * @Author feizhou
	 * @Description 构建主键EntityTable
	 * @Date 下午 3:23 2019/10/9 0009
	 * @Param [entityTable, columnProperties]
	 * @return void
	 **/
	
	private static void buildEntityTable(EntityTable entityTable, List<ColumnProperty> columnProperties) {

		StringBuffer sqlColumns=new StringBuffer();


		Map<String, String> propertyColumn=new HashMap<>();


		for (ColumnProperty columnProperty : columnProperties) {

			String columnName = columnProperty.getColumnName();
			String propertyName = columnProperty.getPropertyName();


			sqlColumns.append(columnName);
			sqlColumns.append(",");


			//构建主键
			if(columnProperty.getIsPK()){
				entityTable.setPKColumn(columnName);
				entityTable.setPKProperty(propertyName);
				entityTable.setIdStrategy(columnProperty.getIdStrategy());
			}

			propertyColumn.put(propertyName,columnName);
		}

		entityTable.setPropertyColumn(propertyColumn);

		//sql查询列
		if(sqlColumns.length()>0){
			entityTable.setSqlColumns(sqlColumns.substring(0,sqlColumns.length()-1));

		}


	}




}
